# coding:utf-8

import os
import re
import logging
import json
from datetime import datetime

from flask import Flask, request
from flask_login import current_user
from redis import StrictRedis
from wtforms import StringField

from common.constant import (
    IM_MESSAGE, DEMAND_WINNER_QUEUE, IM_CLIENT_QUEUE,
    MARKETING_DEMAND_SMS_QUEUE,
    COMMON_API_QUEUE)
from common.utils import QiNiu
from config import config
from app.extensions import (
    bootstrap, mail, db, login_manager, scheduler,
    ma, im_sync_proxy, user_sync_proxy, qi_niu_proxy
)


def is_url(value):
    return re.search(r'^(?:http)s?://', str(value))


def json_loads(value):
    try:
        return json.loads(value)
    except:
        return ''


def to_json_ascii_false(value):
    try:
        return json.dumps(value, ensure_ascii=False)
    except:
        return ''


def timestamp_to_datetime(value):
    return datetime.fromtimestamp(int(value)).strftime('%F') if value else ''


def template_round(value):
    """
    created by chenhj at 27/12/2017

    """
    return round(value, 2)


def encrypt(value):
    """
    create by ld_wu 2018-07-11
    非管理员手机号加密
    :param value:
    :return:
    """
    def _encrypt(text):
        return text[:3] + '****' + text[-4:]
    if not value:
        return ''
    # if current_user.is_administrator:
    #    return value
    if isinstance(value, StringField):
        value.data = _encrypt(value.data)
        return value
    return _encrypt(value)


def create_app(config_name):
    app = Flask(__name__)
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    app.jinja_env.filters['is_url'] = is_url
    app.jinja_env.filters['round'] = template_round
    app.jinja_env.filters['json_loads'] = json_loads
    app.jinja_env.filters['to_json_ascii_false'] = to_json_ascii_false
    app.jinja_env.filters['timestamp_to_datetime'] = timestamp_to_datetime
    app.jinja_env.filters['encrypt'] = encrypt

    # 判断存放录音目录是否存在
    if not os.path.exists(app.config['MEDIA_PATH']):
        os.makedirs(app.config['MEDIA_PATH'])

    app.qiniu = QiNiu()

    # 初始化rabbitmq 生产者
    if app.config['RABBITMQ']:
        from common.producer import Producer
        from common.constant import (
            SMS_QUEUE, MULTI_SMS_QUEUE, WECHAT_QUEUE, CAPTCHA_QUEUE, IM_QUEUE,
            SYNC_USER_QUEUE, ZONE_STAT_EXCHANGE,
            SEVEN_MOOR_AUDIO_UPLOAD_QUEUE, WECHAT_USER_QUEUE,
            WPH_SMS_QUEUE, ASSIGN_RED_PACKET_QUEUE, ALLIANCE_SMS_QUEUE
        )

        app.sms_producer = Producer(SMS_QUEUE)
        app.alliance_producer = Producer(ALLIANCE_SMS_QUEUE)
        app.wph_sms_producer = Producer(WPH_SMS_QUEUE)
        app.multi_sms_producer = Producer(MULTI_SMS_QUEUE)
        app.wechat_producer = Producer(WECHAT_QUEUE)
        app.wechat_user_producer = Producer(WECHAT_USER_QUEUE)
        app.captcha_producer = Producer(CAPTCHA_QUEUE)
        app.im_produce = Producer(IM_QUEUE)
        app.im_msg_producer = Producer(IM_MESSAGE)
        app.im_client_producer = Producer(IM_CLIENT_QUEUE)
        app.sync_user_producer = Producer(SYNC_USER_QUEUE)
        app.zone_stat_exchanger = Producer(ZONE_STAT_EXCHANGE)
        app.sever_moor_audio_upload_producer = Producer(SEVEN_MOOR_AUDIO_UPLOAD_QUEUE)
        app.winner_producer = Producer(DEMAND_WINNER_QUEUE)
        app.marketing_producer = Producer(MARKETING_DEMAND_SMS_QUEUE)
        app.common_producer = Producer(COMMON_API_QUEUE)
        app.assign_red_packet_producer = Producer(ASSIGN_RED_PACKET_QUEUE)
    else:
        app.sms_producer = None
        app.wph_sms_producer = None
        app.alliance_produce = None
        app.multi_sms_producer = None
        app.wechat_producer = None
        app.wechat_user_producer = None
        app.captcha_producer = None
        app.im_produce = None
        app.im_msg_producer = None
        app.sync_user_producer = None
        app.zone_stat_exchanger = None
        app.sever_moor_audio_upload_producer = None
        app.winner_producer = None
        app.im_client_producer = None
        app.marketing_producer = None
        app.common_producer = None
        app.assign_red_packet_producer = None

    app.redis = StrictRedis(
        host=os.getenv('redis_host') or 'localhost',
        db=os.getenv('redis_db') or 0,
        decode_responses=True,
        password=os.getenv('redis_pwd') or None
    )

    bootstrap.init_app(app)
    mail.init_app(app)
    db.init_app(app)
    login_manager.init_app(app)
    ma.init_app(app)
    im_sync_proxy.init_app(app)
    user_sync_proxy.init_app(app)
    qi_niu_proxy.init_app(app)

    # if not app.debug and not app.testing and not app.config['SSL_DISABLE']:
    #     from flask_sslify import SSLify
    #     sslify = SSLify(app)

    from .main import main_bp as main_blueprint
    app.register_blueprint(main_blueprint)

    from .auth import auth_bp as auth_blueprint
    app.register_blueprint(auth_blueprint, url_prefix='/auth')

    from .op import op_bp as op_blueprint
    app.register_blueprint(op_blueprint, url_prefix='/op')

    from .msg import msg_bp as msg_blueprint
    app.register_blueprint(msg_blueprint, url_prefix='/sms')

    from .wechat import wechat_bp as wechat_blueprint, opc_wechat_bp as opc_wechat_blueprint
    app.register_blueprint(wechat_blueprint, url_prefix='/wechat')
    app.register_blueprint(opc_wechat_blueprint, url_prefix='/opc_wechat')

    from .ccws import outbound_bp as outbound_blueprint
    app.register_blueprint(outbound_blueprint, url_prefix='/outbound')

    from .api import api_bp as api_blueprint
    app.register_blueprint(api_blueprint, url_prefix='/api')

    from .axb import axb_bp as axb_blueprint
    app.register_blueprint(axb_blueprint, url_prefix='/axb')

    from .xunke import xunke_bp as xunke_blueprint
    app.register_blueprint(xunke_blueprint, url_prefix='/xunke')

    from .products import product_bp
    app.register_blueprint(product_bp, url_prefix='/product')

    from .compute import compute_bp
    app.register_blueprint(compute_bp, url_prefix='/compute')

    from .api_v2 import api_v2_bp
    app.register_blueprint(api_v2_bp, url_prefix='/api/v2')

    from .war_zone import war_zone_bp
    app.register_blueprint(war_zone_bp, url_prefix='/war_zone')

    from .seven_moor import sever_moor_bp
    app.register_blueprint(sever_moor_bp, url_prefix='/seven_moor')

    from .water import water_bp
    app.register_blueprint(water_bp, url_prefix='/water')

    from .enterprise import enterprise_bp
    app.register_blueprint(enterprise_bp, url_prefix='/enterprise')

    @app.after_request
    def after_clean(resp, *args, **kwargs):
        if resp.status_code == 500:
            db.session.rollback()
        else:
            try:
                db.session.commit()
            except Exception as e:
                logging.error(e)
                db.session.rollback()

        # 若需要跨域则吧以下三句打开
        resp.headers.add('Access-Control-Allow-Origin', request.headers.get("Origin"))
        resp.headers.add('Access-Control-Allow-Credentials', 'true')
        resp.headers.add('Access-Control-Allow-Headers', 'Content-Type')
        resp.headers.add('Access-Control-Allow-Headers', 'token')
        resp.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')

        return resp

    return app


